The world-wide increase in computer networking bandwidth and the availability of networking has enabled large amounts of data to be transmitted quickly and at low cost to many computer users. The availability of great bandwidth has invited the creation of applications which use a network to communicate with other remote computers in real time. One example of such a network application is a multiplayer network gaming application, in which two or more individual users each have a game client on a computer, and where the users' computers are linked to a network that allow them to communicate with each other, perhaps through a centralized server.
Sending and receiving data over a network is a task which is highly complex, and the details of how the sending and receiving is handled should, to the extent possible, be abstracted to an application. In order to allow developers to create applications without needing to address the details of how networks operate, a communications protocol engine negotiates the handling of network traffic and exposes an application program interface (API) whereby the application can express, as a high-level abstraction, what network operations the application wants to perform. Such APIs provide calling conventions by which the application can access the complex resource of the protocol engine. For example, a network API provides calling conventions with which a networking application can use a network. In this way, a network API, such as the DirectPlay® product available from Microsoft Corporation of Redmond, Wash., provides messaging support that largely insulates an application from the underlying network hardware and software.
An application uses the network API by calling exposed methods of the network API. For example, in DirectPlay, in order to send some data across a network, an application calls the IDirectPlay8Peer::SendTo method.
An API may also communicate with the application through one or more callback functions. These functions are implemented in the application, and a pointer thereto is passed to the network API during initialization. When the networking API needs to communicate with the application, it calls the callback function to notify the application about events that have occurred, such as the receipt of data from another node. For example, when a message is received at a target, the DirectPlay® product will call the target application's callback function, with the parameter DPN_MSGID_RECEIVE, and the accompanying data.
Thus, a game developer who wishes to create a multiplayer network game does not need to have the same sophisticated knowledge of networking when a network API is used that the developer would need to use if the application communicated directly with the network hardware and software without the network API.
In order to handle network events efficiently, some network APIs are multithreaded and will fire multiple events concurrently. It is possible that an application will receive callbacks concurrently, and may receive the callbacks while performing some other type of processing. Dealing with concurrency in an application increases the complexity of the program—which may be justified in certain types of applications, but in others, the simplicity of non-concurrency may outweigh the benefits of concurrency. For example, a client game application may simply wish to run a loop where the processing of game events, drawing the screen, and receiving network traffic are handled serially in an endless loop—without the program having to deal with events that come in while, say, the screen is being drawn.
Additionally, client and server applications implementing network games and other networking applications often have very different processing priorities. When a server application such as a network server is being run, low latency is necessary so that network events are processed and the results presented to the user quickly for the best user experience. This is where the “push” architecture in which networking callbacks arrive on multiple threads is useful. A server can spend all of its processing time handling the network session as quickly as possible. However, it may be useful for the server to limit the number of callbacks it can receive, in order to ensure that traffic received may be processed appropriately.
On the other hand, a client application which is responsible for data presentation (for example, rendering complicated graphics) may need to devote more processing time to such data presentation and less to handling network events. Hence, clients such as network clients frequently have a single thread, which runs a graphics loop as fast as the hardware allows. Such clients process network events on a per-frame basis—only at one point on the loop are network events handled. Implementing handling of multithreaded callbacks may be difficult, and will necessitate complex modification of legacy applications to handle callbacks at points other than the designated time in the graphics loop.
Therefore, it can be seen that the desired responsiveness to events such as network events and the balance between responsiveness and resources usage for other purposes varies based on the application being run. Also, it can be seen that it is difficult for a developer to design scalable, robust applications that can support many online players at a time. Thus, there is a need for a networking API which accommodates both applications which process network events on a per frame basis and applications which process events using a push architecture.
Therefore, it can be seen that there is a need for a networking system that allows for applications to use the network interface with or without dedicated threads (and their attendant concurrency issues), and to use the network interface in a unified manner regardless of whether they choose to use dedicated threads.